package com.lms.admin.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lms.admin.base.mapper.SysUserMapper;
import com.lms.admin.base.req.SysUserRoleReq;
import com.lms.admin.base.service.ISysRoleService;
import com.lms.admin.base.service.ISysUserRoleService;
import com.lms.admin.base.service.ISysUserService;
import com.lms.common.entity.SysRole;
import com.lms.common.entity.SysUser;
import com.lms.common.entity.SysUserRole;
import com.lms.common.pure.utils.StringUtil;
import com.lms.common.web.service.impl.WrapperServiceImpl;
import com.lms.common.web.utils.CheckEntityResult;
import com.lms.resource.service.utils.SecurityUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends WrapperServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    private final ISysUserRoleService sysUserRoleService;
    private final ISysRoleService sysRoleService;

    private final PasswordEncoder passwordEncoder;

    @Override
    public IPage<?> queryMapper(Page<SysUser> page, Map<String, Object> p) {
        return this.baseMapper.query(page, p);
    }

    @Override
    public Boolean bindRoles(SysUserRoleReq params) {
        Long userId = params.getUserId();
        List<Long> authorities = params.getAuthorities();
        sysUserRoleService.removeByUserId(userId);
        // 再插入新的角色
        List<SysUserRole> userRoles = new ArrayList<>();
        authorities.forEach(a -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(a);
            userRoles.add(sysUserRole);
        });
        if (!userRoles.isEmpty()) {
            sysUserRoleService.saveBatch(userRoles);
        }
        return true;
    }

    @Override
    public CheckEntityResult beforeInsert(SysUser entity) {
        CheckEntityResult result = CheckEntityResult.getInstance();
        if (StringUtils.isEmpty(entity.getUsername())) {
            result.add("username", "用户名不能为空！");
            return result;
        }
        // 判断新增角色是否存在重复code
        String roleCode = entity.getUsername();
        QueryWrapper<SysUser> params = new QueryWrapper<>();
        params.eq("username", roleCode);
        Long count = this.baseMapper.selectCount(params);
        if (count > 0) {
            result.add("username", "用户名已存在，不允许重复创建！");
            return result;
        }
        entity.setCreateBy(SecurityUtil.getUserName());
        entity.setCreateTime(LocalDateTime.now());
        // 新建用户创建初始密码，初始密码为用户名
        if (StringUtil.isNotEmpty(entity.getPassword())) {
            entity.setPassword(passwordEncoder.encode(entity.getPassword()));
        } else {
            entity.setPassword(passwordEncoder.encode(entity.getUsername()));
        }
        entity.setEnabled(true);
        return result;
    }

    @Override
    public void afterInsert(SysUser entity) {
        // 创建完成之后，初始化赋值普通用户权限
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(entity.getId());
        SysRole role = sysRoleService.getByCode("USER");
        userRole.setRoleId(role.getId());
        sysUserRoleService.saveEntity(userRole);
    }

    @Override
    public CheckEntityResult beforeUpdate(SysUser entity, Serializable id) {
        CheckEntityResult result = CheckEntityResult.getInstance();
        SysUser oldUser = this.getById(id);
        if (!oldUser.getUsername().equals(entity.getUsername())) {
            result.add("username", "用户名不能修改！");
            return result;
        }
        entity.setUpdateBy(SecurityUtil.getUserName());
        entity.setUpdateTime(LocalDateTime.now());
        return result;
    }

    @Override
    public boolean beforeDelete(Serializable id) {
        SysUser user = this.getById(id);
        // 超级管理员用户不能被删除
        return !"admin".equals(user.getUsername());
    }

    @Override
    public void afterDelete(Serializable id) {
        // 删除用户后，需要删除对应的用户与角色关联表信息
        sysUserRoleService.removeByUserId((Long) id);
    }
}
